
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8" />
  <title>原料药变更智能决策系统</title>
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <!-- 国内 CDN -->
  <script src="https://cdn.bootcdn.net/ajax/libs/vue/3.4.21/vue.global.min.js"></script>
  <script src="https://cdn.bootcdn.net/ajax/libs/axios/1.6.7/axios.min.js"></script>
  <link href="https://cdn.bootcdn.net/ajax/libs/daisyui/4.12.10/full.min.css" rel="stylesheet" />
  <script src="https://cdn.tailwindcss.com"></script>
</head>
<body class="bg-gray-50">
  <div id="app" class="p-6">
    <h1 class="text-2xl font-bold mb-4">原料药变更智能决策系统</h1>

    <!-- 决策树 -->
    <div class="bg-white rounded shadow p-4 mb-6">
      <div v-if="tree.length" class="space-y-2">
        <tree-node
          v-for="n in tree"
          :key="n.id"
          :node="n"
          :level="0"
          @select="handleSelect"
        ></tree-node>
      </div>
      <div v-else class="text-sm text-gray-500">加载中…</div>
    </div>

    <!-- 节点详情抽屉 -->
    <div v-if="detail" class="fixed inset-0 bg-black bg-opacity-30 flex items-center justify-center">
      <div class="bg-white rounded shadow-lg p-6 w-full max-w-md">
        <h2 class="text-lg font-semibold mb-2">{{ detail.label }}</h2>
        <p class="text-sm text-gray-600 mb-1">类别：<span class="font-medium">{{ detail.category || '-' }}</span></p>
        <p class="text-sm text-gray-600 mb-1">法规：<span class="font-medium">{{ detail.regulation || '-' }}</span></p>
        <p class="text-sm text-gray-600 mb-4">材料：<span class="font-medium">{{ detail.materials || '-' }}</span></p>
        <div class="flex justify-end gap-2">
          <button class="btn btn-sm btn-outline" @click="detail=null">关闭</button>
          <button class="btn btn-sm btn-primary" @click="addToPath(detail)">加入路径</button>
        </div>
      </div>
    </div>

    <!-- 已选路径 -->
    <div class="bg-white rounded shadow p-4">
      <div class="flex justify-between items-center mb-2">
        <h3 class="font-semibold">已选决策路径</h3>
        <button class="btn btn-sm btn-accent" @click="exportPdf">导出 PDF</button>
      </div>
      <ol class="list-decimal list-inside text-sm space-y-1">
        <li v-for="n in path" :key="n.id">{{ n.label }}</li>
      </ol>
      <p v-if="!path.length" class="text-sm text-gray-500">请点击节点开始决策</p>
    </div>
  </div>

  <script>
    const { createApp, ref, onMounted } = Vue;

    // 树形组件
    const TreeNode = {
      name: 'TreeNode',
      props: ['node', 'level'],
      emits: ['select'],
      template: `
        <div :style="{marginLeft: level*24+'px'}" class="border-l-2 border-blue-300 pl-3 py-1">
          <div
            class="flex items-center justify-between p-2 rounded hover:bg-blue-50 cursor-pointer"
            @click="$emit('select', node)"
          >
            <span class="text-sm">{{ node.label }}</span>
            <span class="text-xs text-gray-400">{{ node.node_type }}</span>
          </div>
          <div v-if="node.children && node.children.length">
            <tree-node
              v-for="c in node.children"
              :key="c.id"
              :node="c"
              :level="level+1"
              @select="$emit('select', $event)"
            ></tree-node>
          </div>
        </div>
      `
    };

    createApp({
      components: { TreeNode },
      setup() {
        const nodes = ref([]);
        const tree = ref([]);
        const detail = ref(null);
        const path = ref([]);

        // 拉取平铺节点并构造成树
        const load = async () => {
          const { data } = await axios.get('http://localhost:8000/api/nodes');
          nodes.value = data;
          buildTree();
        };

        const buildTree = () => {
          const map = {};
          nodes.value.forEach(n => {
            map[n.id] = { ...n, children: [] };
          });
          const roots = [];
          nodes.value.forEach(n => {
            if (n.next_nodes) {
              n.next_nodes.split(',').forEach(cid => {
                if (map[cid]) map[n.id].children.push(map[cid]);
              });
            }
            // 无父节点则视为根
            const hasParent = nodes.value.some(p => p.next_nodes && p.next_nodes.split(',').includes(n.id));
            if (!hasParent) roots.push(map[n.id]);
          });
          tree.value = roots;
        };

        const handleSelect = (n) => {
          // 末端节点才弹详情
          if (!n.children || !n.children.length) {
            detail.value = n;
          }
        };

        const addToPath = (n) => {
          path.value.push(n);
          detail.value = null;
        };

        const exportPdf = async () => {
          if (!path.value.length) return alert('路径为空');
          const { data } = await axios.post('http://localhost:8000/api/decision/report', {
            node_ids: path.value.map(n => n.id)
          });
          window.open(data.pdf_url, '_blank');
        };

        onMounted(load);

        return { tree, detail, path, handleSelect, addToPath, exportPdf };
      }
    }).mount('#app');
  </script>
</body>
</html>
